<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <script>
        // generator函数 可以通过yield关键字，将函数挂起，为了改变执行流提供了可能，同时为了做异步编程提供了方案
        // 它普通函数的区别
        // 1.function后面 函数名之前有个*
        // 2.只能在函数内部使用yield表达式，让函数挂起

        function* func(){
            console.log('one');
            yield 2;
            console.log('two');
            yield 3;
            console.log('end');
        }
        let fn = func();
        console.log(fn);
        console.log(fn.next());
        console.log(fn.next());
        console.log(fn.next());

        // 总结：generator函数是分段执行的，yield语句是暂停执行 而next()恢复执行

        function* add() {
            console.log('start');
            // x 不是yield '2'的返回值，它是next()调用 恢复当前yield() 执行传入的实参
            let x = yield '2';
            console.log('one:'+x);
            let y = yield '3';
            console.log('two:'+y);
            return x+y;
        }
        const fn2 = add();
        console.log(fn2.next()); //{value:'2',done:false}
        console.log(fn2.next(20)); //{value:'3',done:false}
        console.log(fn2.next(30)); //{value:'50',done:true}
        console.log(fn2.return(100))// 可手动return

        // 使用场景：为不具备Iterator接口的对象提供了遍历的操作
        function* objectEntries(obj){
            // 获取对象的所有的key保存到数组[name,age]
            const propKeys = Object.keys(obj);
            for (const propkey of propKeys){
                yield [propkey,obj[propkey]];
            }
        }

        const obj = {
            name:'小马哥',
            age:18
        }
        obj[Symbol.iterator] = objectEntries;
        console.log(obj);

        for (let arr of objectEntries(obj)){
            console.log(arr);
        }

        for (let [key,value] of objectEntries(obj)){
            console.log(`${key}:${value}`);
        }
    </script>
</body>
</html>